﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Go.Tools;

namespace Go.Model
{
    class RulesValidator
    {
        private static RulesValidator _instance = null;
        private static Dictionary<Coordinate, Position> _board;
        private static List<Player> _players;

        public static RulesValidator instance(){
            if(_instance == null)
                throw new System.ArgumentException("No es posible tomar la instancia del RulesValidator");
            return _instance;
        }

        public static RulesValidator instance(Dictionary<Coordinate, Position> board, List<Player> players )
        {
            _players = players;
            _board = board;
            if (_instance == null)
                _instance = new RulesValidator();
            return _instance;
        }
        
        private RulesValidator(){}

        //Devuelve true si con la posicion pasada es el final del juego
        //Se le pasa por parametro la ultima y la ante ultima posiciones jugadas
        public bool isEndOfGame(Player aPlayer)
        {
            return isFinishedAPlayerWin(aPlayer)
                    || isFinishedNobodyWantPlay(aPlayer)
                        || isThereNoSpaceOnBoard();
        }

        public bool isTheWinner(Player aPlayer)
        {
            foreach (Group aGroup in aPlayer.Opponent.Groups)
            {
                if (aGroup.isDead())
                    return true;
            }
            return false;
        }



        //Devuelve true si con la posicion pasada es el final del juego
        // se le pasa la ultima posicion jugada
        public bool isFinishedAPlayerWin(Player lastPlayerWhosPlayed)
        {
            //El unico grupo que puede morir es uno oponente
            foreach (Group aGroup in lastPlayerWhosPlayed.Opponent.Groups)
            {
                if (aGroup.isDead())
                    return true;
            }
            return false;
        } 

        //Devuelve true si no quedan posiciones libres
        public bool isThereNoSpaceOnBoard()
        {
            int stonesInGame = 0;
            foreach (Player aPlayer in _players) {
                stonesInGame += aPlayer.stones().Count;
            }
            return stonesInGame==_board.Count;
        }
        
        // Devuelve true si ambos jugadores hicieron paso en sus ultimas jugadas
        public bool isFinishedNobodyWantPlay(Player aPlayer)
        {
            //Se tiene q fijar tb si ya pudo jugar
            return (aPlayer.LastPlayed == null) && (aPlayer.Opponent.HasMadeAFirstMove) && (aPlayer.Opponent.LastPlayed == null);
        }

        // Devuelve true si el jugador pasado puede jugar una piedra alli.
        // Osea que no se suicide. Si es Null devuelve true
        public bool isValidPlayStone(Coordinate aCoord, Player aPlayer) { 
            return _board[aCoord].isEmpty();
        }


        // Devuelve true si el jugador pasado puede jugar una piedra alli.
        // Osea que no se suicide. Si es Null devuelve true
        public Position getPosition(Coordinate aCoord)
        {
            return _board[aCoord];
        }

    }
}
